import {Injectable} from '@angular/core';
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, CanActivateChild} from '@angular/router';
import {Observable, of} from 'rxjs';
import {mergeMap, switchMap} from 'rxjs/internal/operators';
import {NavController, ToastController} from '@ionic/angular';
import {Storage} from '@ionic/storage';
import {AppConfig} from '../common/app-config.enum';
import {fromPromise} from 'rxjs/internal/observable/fromPromise';
import {HttpService} from '../services/http.service';
import {UrlAndOPT} from '../common/url-and-opt.enum';

/**
 * 用户角色守卫
 */
@Injectable({
  providedIn: 'root'
})
export class UserRoleGuard implements CanActivate, CanActivateChild {

  private userInfo: any;

  constructor(private navCtrl: NavController,
              private storage: Storage,
              private toastCtrl: ToastController,
              private service$: HttpService
  ) {
  }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    // 获取userRole参数，如有参数说明需要指定的角色才可进入，无参数表示只要开通资金存管就可进入，无固定角色要求
    const userRole = next.params['userRole'];
    return fromPromise(this.storage.get(AppConfig.USER_INFO))
      .pipe(
        mergeMap(userInfo => {
          this.userInfo = userInfo;
          if (userInfo[AppConfig.USER_ROLE_KEY]) { // 当前用户拥有角色(已开通资金存管)
            return this.getResult(userRole, userInfo);
          } else {
            // 在线验证当前用户是否开通资金存管
            return this.service$.doRequest(UrlAndOPT.auth_user_role, {userId: userInfo[AppConfig.USER_INFO_KEY]});
          }
        }),
        mergeMap(res => {
          if (typeof res === 'object') {
            if (res[AppConfig.USER_ROLE_KEY]) { // 在线验证已拥有角色(已开通资金存管)
              return fromPromise(this.storage.set(AppConfig.USER_INFO, { // 更新本地存储
                ...this.userInfo,
                [AppConfig.USER_ROLE_KEY]: res[AppConfig.USER_ROLE_KEY]
              }))
                .pipe(
                  switchMap(() => {
                    return this.getResult(userRole, res);
                  })
                );
            } else {
              // 在线验证后仍无角色(未开通资金存管)，前往实名认证
              this.navCtrl.navigateForward(['/auth/user-account', {userRole: userRole || ''}]);
              return of(false);
            }
          } else {
            return of(res);
          }
        })
      );
  }

  canActivateChild(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return this.canActivate(next, state);
  }

  // 获取角色比对结果
  private getResult(userRole: any, userInfo: any): Observable<boolean> {
    if (!userRole || userRole * 1 === userInfo[AppConfig.USER_ROLE_KEY]) { // 无固定角色要求或角色与要求一致，可进入
      return of(true);
    } else {
      const msg = userInfo[AppConfig.USER_ROLE_KEY] === 1 ? '出借人不可进行借款' : '借款人不能进行出借投资';
      this.showToast(msg);
      return of(false); // 用户有角色，请求有角色要求，但角色不一致，不可进入并给予提示
    }
  }

  // 显示通知消息
  private async showToast(msg) {
    const toast = await this.toastCtrl.create({
      message: msg || '请求数据失败',
      position: AppConfig.TOAST_POSITION,
      duration: AppConfig.TOAST_DURATION * 1
    });
    return toast.present();
  }

}
